package com.ldn.basic.utils;

import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * @author 李大牛家的牛 (scafel@163.com) 
 * @createDate 2024/7/9 - 17:21
 * @description ...
 **/
@Slf4j
@Component
public class AppSpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
        AppSpringContextUtil.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        checkApplicationContext();
        return applicationContext;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName, Class<T> expectedType) {
        checkApplicationContext();
        // 从ApplicationContext获取指定名称的bean
        Object bean = applicationContext.getBean(beanName);

        // 检查获取的bean是否是期望的类型
        if (expectedType.isInstance(bean)) {
            return (T) bean;
        } else {
            throw new IllegalStateException("Bean '" + beanName + "' is not an instance of " + expectedType.getName());
        }
    }

    public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationClass) {
        checkApplicationContext();
        return applicationContext.getBeansWithAnnotation(annotationClass);
    }

    public static <T> T getBean(Class<T> requiredType) {
        checkApplicationContext();
        log.info("requiredType:" + requiredType);
        return applicationContext.getBean(requiredType);
    }

    private static void checkApplicationContext() {
        log.info("applicationContext:" + applicationContext);
        if (AppSpringContextUtil.applicationContext == null) {
            log.error("applicationContext属性为null,请检查是否注入了AppSpringContextUtils!");
            throw new RuntimeException("applicationContext属性为null,请检查是否注入了AppSpringContextUtils!");
        }
    }

}